//交叉类型(&),如果一个值的类型是 A&B，我们能够 确定的是它包含了 A 和 B中所有成员
function extend<T,U>(first:T,second:U):T & U{
    let result=<T&U>{};
    for(let id in first){
        (<any>result)[id]=first[id]
    }
    for(let id in second){
        if(!result.hasOwnProperty(id)){
            (<any>result)[id]=second[id]
        }
    }
    return result;
}

class Person {
    constructor(public name: string) { };
    fly(){}
}
interface Loggable {
    log(): void;
}
class ConsoleLogger implements Loggable {
    log() {
        // ...
    }
}
var jim=extend(new Person("jim"),new ConsoleLogger());
jim.name;
jim.log(); 

//联合类型(|),如果一个值的类型是 A | B，我们能够 确定的是它包含了 A 和 B中共有的成员
interface Bird{
    fly():void;
    layEggs():void;
}
interface fish{
    swim():void;
    layEggs():void;
}
function getSmallPet():fish|Bird{
    return <Bird>{};
}
let pet = getSmallPet();
pet.layEggs(); // okay
pet.fly();    // errors

 //类型断言(如果编译器无法去除null和undefined,你可以使用类型断言手动去除，语法是添加后缀！)
 function broken(name:string|null):string{
     function postfix(epithet:string){
         return name!.charAt(0)+' .the'+epithet;
     }
     name=name||'Bob';
     return postfix("great");
 }





